iT邦幫忙

0

[Laravel] Eloquent ORM 1-1/ 1-*/ *-*( Many to Many)

  • 分享至 

  • xImage
  •  

前言

這篇稍微介紹 ORM 操作資料庫關聯的用法。「1對1」和「1對多」作法相同,須在自己的 tabel 加 Foreign Key,「多對多」需要建立一個關聯表(pivot table)。 感謝 Charleen 的文章-Eloquent: Many to Many (前言:創建多對多資料表,踩坑大全)
舉餐廳的例子:

  • 一對一 -- 每間餐廳對應一張菜單。
  • 一對多 -- 每張菜單有多道菜。
  • 多對多 -- 每個人都可以開多個餐廳,每個餐廳可能有多個擁有者。

「1對1」「1對多」

  1. 在 menu table 的 Migration 中設定 foreign key 欄位
public function up()
    {
        Schema::create('menus', function (Blueprint $table) {
            $table->unsignedBigInteger('restaurant_id');
        }
    }

2-1. 在 menu 自己的 Model 中加入 restaurant 函式,用 belongsTo 取出關聯的資料

public function restaurant(){
    return $this->belongsTo('App\Restaurant');
}

2-2. 或是在 restaurant 的 Model 中加入 menu 函式,用 hasOne 或是 hasMany 取出關聯的資料

public function menu()
    {
        return $this->hasOne('App\Menu');
    }
}
  1. 在 Restaurant 的 Controller 中,呼叫函式
    Restaurant::with('users')->first()->menu;

{
"id": 1,
"img": "http://localhost:8000/storage/JQmggLcgfEqweLSMzqoqm4x8WV4DIaU5RitsYgjX.jpeg",
"restaurant_id": 1
}

Restaurant::with('menu')->first();

{
"id": 1,
"name": "veg_sasa",
"menu": {
"id": 1,
"img": "http://localhost:8000/storage/JQmggLcgfEqweLSMzqoqm4x8WV4DIaU5RitsYgjX.jpeg",
"restaurant_id": 1
}
}

「多對多」

  1. 建立 pivot 表,由兩個 Model 的 首字字母順序建立,且表名稱需為單數。
    php artisan make:migration create_restaurant_user_table
    建立 Model: php artisan make:model RestaurantUser

若是直接用 php artisan make:model UserRestaurant -mc,會自動產生有複數的 table(user_restaurants),這樣會有錯
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'testorm.restaurant_user' doesn't exist

  1. 必須要在關聯 Model 中定義使用的 pivot 表名稱
  • protected $table = 'restaurant_user'; 若model中沒有特地寫這行, model會沒辦法對應到資料庫的 table, 因為他會去找預設的 restaurant_users 來作存取
  1. 在 User 或 Restaurant 的 Model 加上函式對應
public function users()
    {
        return $this->belongsToMany('App\User');
    }
  1. 可以在 Model 中將 pivot 欄位隱藏(非必要)
protected $hidden = [
        'password', 'remember_token','created_at', 'updated_at','pivot'
    ];
  1. 撈關聯資料 User::with('restaurants')->latest('id')->first();
{
    "id": 2,
    "name": "erin",
    "restaurants": [
        {
            "id": 1,
            "name": "veg_sasa"
        },
        {
            "id": 2,
            "name": "veg_elephant"
        }
    ]
}

反向撈關聯資料 Restaurant::with('users')->latest('id')->first();

{
    "id": 2,
    "name": "veg_elephant",
    "users": [
        {
            "id": 2,
            "name": "erin"
        },
        {
            "id": 1,
            "name": "sarah"
        }
    ]
}

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言